package com.newlink.building.userinfo.utils;

import android.util.Log;

/**
 * @Author: Jake
 * @Date: 2024-04-24
 * @Description:
 */
public class Module_UserInfo_CRC16CCITT {
    public static short calculateCRC16_CCITT(byte[] data) {
        short crc = 0x0000;

        for (byte byteValue : data) {
            short crcByte = byteValue;

            if (data.length > 1) {
                crcByte = reverseBits(byteValue);
            }

            crc ^= crcByte << 8;
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x8000) != 0) {
                    crc = (short) ((crc << 1) ^ 0x1021);
                } else {
                    crc = (short) (crc << 1);
                }
            }
        }
        crc = reverseBitsUInt16(crc);

        Log.e("jake", "result crc is = " + crc);

        return crc;
    }

    public static int calculateCRC16_CCITT2(byte[] data) {
        short crc = 0x0000;

        for (byte byteValue : data) {
            short crcByte = byteValue;

            if (data.length > 1) {
                crcByte = reverseBits(byteValue);
            }

            crc ^= crcByte << 8;
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x8000) != 0) {
                    crc = (short) ((crc << 1) ^ 0x1021);
                } else {
                    crc = (short) (crc << 1);
                }
            }
        }
        crc = reverseBitsUInt16(crc);

        Log.e("jake", "result crc is = " + crc);

        int unsignedShort = crc & 0xFFFF;
        Log.e("jake", "result crc unsignedShort is = " + unsignedShort);
        return unsignedShort;
    }

    private static final int POLYNOMIAL = 0x1021;
    private static final int INITIAL_VALUE = 0x0000;

    public static int calculateCRC(byte[] data) {
        int crc = INITIAL_VALUE;

        for (byte b : data) {
            crc ^= (b << 8);

            for (int i = 0; i < 8; i++) {
                if ((crc & 0x8000) != 0) {
                    crc = (crc << 1) ^ POLYNOMIAL;
                } else {
                    crc = crc << 1;
                }
            }
        }

        return crc & 0xFFFF;
    }

    //	private static final int POLYNOMIAL = 0x1021; // CRC-CCITT Polynomial
//	private static final int INITIAL_VALUE = 0x0000;
    private static final int XOR_OUT = 0x0000;

    public static int calculateCRC2(byte[] data) {
        int crc = INITIAL_VALUE;

        for (byte b : data) {
            crc ^= (b & 0xFF) << 8;

            for (int i = 0; i < 8; i++) {
                if ((crc & 0x8000) != 0) {
                    crc = (crc << 1) ^ POLYNOMIAL;
                } else {
                    crc = crc << 1;
                }
            }
        }

        crc ^= XOR_OUT;
        return crc & 0xFFFF;
    }


    public static int calculateCRC3(byte[] data) {
        int crc = INITIAL_VALUE;

        for (byte b : data) {
            crc ^= (b & 0xFF) << 8;
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x8000) != 0) {
                    crc = (crc << 1) ^ POLYNOMIAL;
                } else {
                    crc = crc << 1;
                }
            }
        }

        crc ^= XOR_OUT;
        return crc & 0xFFFF;
    }

    public static byte reverseBits(byte byteValue) {
        byte value = byteValue;
        byte reversedByte = 0;
        for (int i = 0; i < 8; i++) {
            reversedByte = (byte) ((reversedByte << 1) | (value & 1));
            value >>= 1;
        }
        return reversedByte;
    }

    public static short reverseBitsUInt16(short value) {
        short result = 0;
        short remainingBits = value;

        for (int i = 0; i < 16; i++) {
            result = (short) ((result << 1) | (remainingBits & 1));
            remainingBits >>= 1;
        }

        return result;
    }

    public static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }

//	public static void main(String[] args) {
//		byte[] data = {0x01, 0x02, 0x3c, 0x68, (byte) 0xfc, (byte) 0xa5, (byte) 0xd8, (byte) 0x88, 0x0d, (byte) 0x94, 0x39, 0x0e, (byte) 0xab, 0x16, 0x48, 0x04, (byte) 0x9a, (byte) 0x89};
//		short crc = calculateCRC16_CCITT(data);
//		System.out.printf("CRC-16/CCITT: %04X\n", crc);
//	}

}
